#include <iostream>
#include <thread>
#include <mutex>
#include <shared_mutex>
#include <vector>
#include <chrono>
#include <time.h>
#include <string.h>
using namespace std;

string get_now_timestamp()
{
    time_t t = time(nullptr);
    char buf[64];
    strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", localtime(&t));

    // 获取当前时间点
    auto currentTime = std::chrono::system_clock::now();
    // 将时间点转换为毫秒级时间戳
    auto milliseconds = std::chrono::duration_cast<std::chrono::milliseconds>(currentTime.time_since_epoch()).count();
    // 将毫秒级时间戳转换为time_t（秒）和毫秒部分
    // std::time_t seconds = milliseconds / 1000;
    int remainingMilliseconds = milliseconds % 1000;
    sprintf(buf + strlen(buf), ".%03d", remainingMilliseconds);

    return buf;
}

shared_mutex rw_mutex;

void read_thread(int count, int &data)
{
    cout << "read thread start: " << get_now_timestamp() << endl;
    for (int i = 0; i < count; i++)
    {
        {
            shared_lock<shared_mutex> lock(rw_mutex);
            data ++;
            cout << "id: " << count <<" data: " << data << endl;
            this_thread::sleep_for(chrono::seconds(1));
        }
        this_thread::sleep_for(chrono::milliseconds(10));
    }
    cout << "read thread end: " << get_now_timestamp() << endl;
}

void write_thread(int count, int &data)
{
    cout << "id: " << count <<" -- write thread start: " << get_now_timestamp() << endl;
    for (int i = 0; i < count; i++)
    {
        {
            unique_lock<shared_mutex> lock(rw_mutex);
            data ++;
            cout << "id: " << count <<" data: " << data << endl;
            this_thread::sleep_for(chrono::seconds(1));
        }
        this_thread::sleep_for(chrono::milliseconds(10));
    }
    cout << "id: " << count <<" -- write thread end: " << get_now_timestamp() << endl;
}

int main()
{
    std::vector<std::thread> threads;
    int data = 0;
    threads.emplace_back(read_thread, 10, ref(data));
    this_thread::sleep_for(chrono::milliseconds(100));
    threads.emplace_back(read_thread, 11, ref(data));

    for (auto &t : threads)
    {
        t.join();
    }
    threads.clear();
    data = 0;

    threads.emplace_back(write_thread, 10, ref(data));
    this_thread::sleep_for(chrono::milliseconds(100));
    threads.emplace_back(write_thread, 11, ref(data));
    for (auto &t : threads)
    {
        t.join();
    }

    return 0;
}

/* 共享锁/读锁 测试结果
read thread start: 2024-10-18 09:54:45.063
read thread start: 2024-10-18 09:54:45.163
...
read thread end: 2024-10-18 09:54:55.165
read thread end: 2024-10-18 09:54:56.275

共享锁/读锁: 用时: 11s
 */

/* 独占锁/写锁 测试结果
id: 10 -- write thread start: 2024-10-18 09:58:06.403
id: 11 -- write thread start: 2024-10-18 09:58:06.503
...
id: 10 -- write thread end: 2024-10-18 09:58:25.415
id: 11 -- write thread end: 2024-10-18 09:58:27.425

独占锁/写锁: 用时: 22s
 */